File "admin.php"
Full path: /home/dora/public_html/wp-content/themes/bricks/includes/admin.php
File size: 39.35 KB
MIME-type: --
Charset: utf-8
<?php
namespace Bricks;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
class Admin {
const EDITING_CAP = 'edit_posts';
public function __construct() {
// add_action( 'wp_dashboard_setup', [ $this, 'wp_dashboard_setup' ] );
add_action( 'after_switch_theme', [ $this, 'set_default_settings' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
add_action( 'enqueue_block_editor_assets', [ $this, 'gutenberg_scripts' ] );
add_action( 'admin_menu', [ $this, 'admin_menu' ] );
add_action( 'admin_notices', [ $this, 'admin_notices' ] );
add_action( 'admin_notices', [ $this, 'admin_notice_regenerate_css_files' ] );
add_filter( 'display_post_states', [ $this, 'add_post_state' ], 10, 2 );
add_filter( 'admin_body_class', [ $this, 'admin_body_class' ] );
add_filter( 'image_size_names_choose', [ $this, 'image_size_names_choose' ] );
add_action( 'admin_init', [ $this, 'save_editor_mode' ] );
add_filter( 'admin_url', [ $this, 'admin_url' ] );
add_action( 'wp_ajax_bricks_import_global_settings', [ $this, 'import_global_settings' ] );
add_action( 'wp_ajax_bricks_export_global_settings', [ $this, 'export_global_settings' ] );
add_action( 'wp_ajax_bricks_save_settings', [ $this, 'save_settings' ] );
add_action( 'wp_ajax_bricks_reset_settings', [ $this, 'reset_settings' ] );
add_action( 'edit_form_after_title', [ $this, 'builder_tab_html' ], 10, 2 );
add_filter( 'page_row_actions', [ $this, 'row_actions' ], 10, 2 );
add_filter( 'post_row_actions', [ $this, 'row_actions' ], 10, 2 );
add_filter( 'manage_' . BRICKS_DB_TEMPLATE_SLUG . '_posts_columns', [ $this, 'bricks_template_posts_columns' ] );
add_action( 'manage_' . BRICKS_DB_TEMPLATE_SLUG . '_posts_custom_column', [ $this, 'bricks_template_posts_custom_column' ], 10, 2 );
// Export template
add_filter( 'bulk_actions-edit-bricks_template', [ $this, 'bricks_template_bulk_action_export' ] );
add_filter( 'handle_bulk_actions-edit-bricks_template', [ $this, 'bricks_template_handle_bulk_action_export' ], 10, 3 );
// Import template
add_action( 'admin_footer', [ $this, 'import_templates_form' ] );
// Add template type meta box
add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] );
add_action( 'save_post', [ $this, 'meta_box_save_post' ] );
}
/**
* Add meta box: Template type
*
* @since 1.0
*/
public function add_meta_boxes() {
add_meta_box(
'meta-box-template-type',
esc_html__( 'Template Type', 'bricks' ),
[ $this, 'meta_box_template_type' ],
BRICKS_DB_TEMPLATE_SLUG,
'side',
'high'
);
}
/**
* Meta box: Template type render
*
* @since 1.0
*/
public function meta_box_template_type( $post ) {
$template_type = get_post_meta( $post->ID, BRICKS_DB_TEMPLATE_TYPE, true );
$template_types_options = Setup::$control_options['templateTypes'];
?>
<p><label for="bricks_template_type"><?php esc_html_e( 'Select template type:', 'bricks' ); ?></label></p>
<select name="bricks_template_type" id="bricks_template_type" style="width: 100%">
<option value=""><?php esc_html_e( 'Select', 'bricks' ); ?></option>
<?php
foreach ( $template_types_options as $key => $value ) {
echo '<option value=' . $key . ' ' . selected( $key, $template_type ) . '>' . $value . '</option>';
}
?>
</select>
<?php
}
/**
* Meta box: Save/delete template type
*
* @since 1.0
*/
public function meta_box_save_post( $post_id ) {
$template_type = ! empty( $_POST['bricks_template_type'] ) ? $_POST['bricks_template_type'] : false;
if ( $template_type ) {
// Get previous template type
$previous_type = get_post_meta( $post_id, BRICKS_DB_TEMPLATE_TYPE, true );
// Update new template type
update_post_meta( $post_id, BRICKS_DB_TEMPLATE_TYPE, $template_type );
// Convert template types into content area (header, content, footer)
$previous_type = $previous_type ? Database::get_bricks_data_key( $previous_type ) : false;
$new_type = Database::get_bricks_data_key( $template_type );
// If content areas exist and are different, them migrate data
if ( $previous_type && $new_type && $previous_type !== $new_type ) {
// Get the data from the previous content area
$previous_data = get_post_meta( $post_id, $previous_type, true );
// Save data using the new content area
update_post_meta( $post_id, $new_type, $previous_data );
// Delete data from previous content area
delete_post_meta( $post_id, $previous_type );
}
}
}
/**
* Register dashboard widget
*
* NOTE: Not in use, yet.
*
* @since 1.0
*/
public function wp_dashboard_setup() {
wp_add_dashboard_widget(
'bricks_dashboard_widget',
esc_html__( 'Bricks News', 'bricks' ),
[ $this, 'dashboard_widget' ]
);
// Move Bricks dashboard widget to the top
// https://codex.wordpress.org/Dashboard_Widgets_API#Advanced:_Forcing_your_widget_to_the_top
global $wp_meta_boxes;
$normal_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
$sorted_dashboard = array_merge( [ 'bricks_dashboard_widget' => $normal_dashboard['bricks_dashboard_widget'] ], $normal_dashboard );
$wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard;
}
/**
* Render dashboard widget
*
* @since 1.0
*/
public function dashboard_widget() {
// Get remote feed from Bricks blog
$feed = Api::get_feed();
if ( count( $feed ) ) {
echo '<ul class="bricks-dashboard-feed-wrapper">';
foreach ( $feed as $post ) {
echo '<li>';
echo '<a href="' . $post['permalink'] . '?utm_source=wp-admin&utm_medium=wp-dashboard-widget&utm_campaign=feed" target="_blank">' . $post['title'] . '</a>';
echo '<p>' . $post['excerpt'] . '</p>';
echo '</li>';
}
echo '</ul>';
}
}
/**
* Post custom column
*
* @since 1.0
*/
public function posts_custom_column( $column, $post_id ) {
if ( $column === 'template' ) {
$post_template_id = 0;
if ( $post_template_id ) {
echo '<a href="' . Helpers::get_builder_edit_link( $post_id ) . '" target="_blank">' . $post_template['title'] . '</a>';
} else {
echo '-';
}
}
}
/**
* Add bulk action "Export"
*
* @since 1.0
*/
public function bricks_template_bulk_action_export( $actions ) {
$actions[ BRICKS_EXPORT_TEMPLATES ] = esc_html__( 'Export', 'bricks' );
return $actions;
}
/**
* Handle bulk action "Export"
*
* @param string $redirect_url Redirect URL.
* @param string $doaction Action to run.
* @param array $items Items to run action on.
*
* @since 1.0
*/
public function bricks_template_handle_bulk_action_export( $redirect_url, $doaction, $items ) {
if ( $doaction === BRICKS_EXPORT_TEMPLATES ) {
$this->export_templates( $items );
}
return $redirect_url;
}
/**
* Export templates
*
* @param array $items Items to export.
*
* @since 1.0
*/
public function export_templates( $template_ids ) {
$files = [];
$wp_upload_dir = wp_upload_dir();
$temp_path = trailingslashit( $wp_upload_dir['basedir'] ) . BRICKS_TEMP_DIR;
// Create temp path if it doesn't exist
wp_mkdir_p( $temp_path );
foreach ( $template_ids as $template_id ) {
$file_data = Templates::export_template( $template_id );
$file_path = trailingslashit( $temp_path ) . $file_data['name'];
$file_put_contents = file_put_contents( $file_path, $file_data['content'] );
$files[] = [
'path' => $file_path,
'name' => $file_data['name'],
];
}
// Check if ZipArchive PHP extension exists
if ( ! class_exists( '\ZipArchive' ) ) {
return new \WP_Error( 'ziparchive_error', 'Error: ZipArchive PHP extension does not exist.' );
}
// Create ZIP file
$zip_filename = 'templates-' . date( 'Y-m-d' ) . '.zip';
$zip_path = trailingslashit( $temp_path ) . $zip_filename;
$zip_archive = new \ZipArchive();
$zip_archive->open( $zip_path, \ZipArchive::CREATE );
foreach ( $files as $file ) {
$zip_archive->addFile( $file['path'], $file['name'] );
}
$zip_archive->close();
// Delete template JSON files
foreach ( $files as $file ) {
unlink( $file['path'] );
}
header( 'Content-Type: application/octet-stream' );
header( 'Content-Disposition: attachment; filename=' . $zip_filename );
header( 'Cache-Control: must-revalidate' );
header( 'Expires: 0' );
header( 'Pragma: public' );
header( 'Content-Length: ' . filesize( $zip_path ) );
@ob_end_flush();
@readfile( $zip_path );
unlink( $zip_path );
die;
}
/**
* Import templates form
*
* @since 1.0
*/
public function import_templates_form() {
global $current_screen;
if ( ! $current_screen ) {
return;
}
// Show import templates form on "My Templates" admin page
if ( $current_screen->id === 'edit-' . BRICKS_DB_TEMPLATE_SLUG ) {
?>
<div id="bricks-admin-import-wrapper">
<a id="bricks-admin-import-action" class="page-title-action bricks-admin-import-toggle"><?php esc_html_e( 'Import template', 'bricks' ); ?></a>
<div id="bricks-admin-import-form-wrapper">
<p><?php esc_html_e( 'Select and import your template JSON/ZIP file from your computer.', 'bricks' ); ?></p>
<form id="bricks-admin-import-form" method="post" enctype="multipart/form-data">
<p><input type="file" name="files" id="bricks_import_files" accept=".json,application/json,.zip,application/octet-stream,application/zip,application/x-zip,application/x-zip-compressed" multiple required></p>
<input type="submit" class="button button-primary button-large" value="<?php echo esc_attr__( 'Import template', 'bricks' ); ?>">
<button class="button button-large bricks-admin-import-toggle"><?php esc_html_e( 'Cancel', 'bricks' ); ?></button>
<input type="hidden" name="action" value="bricks_import_template">
<?php wp_nonce_field( 'bricks-nonce', 'nonce' ); // @since 1.5.4 ?>
</form>
<i class="close bricks-admin-import-toggle dashicons dashicons-no-alt"></i>
</div>
</div>
<?php
}
}
/**
* Import global settings
*
* @since 1.0
*/
public function import_global_settings() {
// @since 1.5.4
if ( ! check_ajax_referer( 'bricks-nonce', 'nonce', false ) ) {
wp_send_json_error( 'verify_nonce: "bricks-nonce" is invalid.' );
}
// @since 1.5.4
if ( ! Capabilities::current_user_has_full_access() ) {
wp_send_json_error( 'verify_request: Sorry, you are not allowed to perform this action.' );
}
// Load WP_WP_Filesystem for temp file URL access
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
// Import single JSON file
$files = $_FILES['files']['tmp_name'];
$settings = [];
$updated = false;
foreach ( $files as $file ) {
$settings = json_decode( $wp_filesystem->get_contents( $file ), true );
}
if ( is_array( $settings ) && count( $settings ) ) {
$updated = update_option( BRICKS_DB_GLOBAL_SETTINGS, $settings );
}
wp_send_json_success(
[
'settings' => $settings,
'updated' => $updated,
]
);
}
/**
* Generate and download JSON file with global settings
*
* @since 1.0
*/
public static function export_global_settings() {
// Verify nonce
if ( ! check_ajax_referer( 'bricks-nonce', 'nonce', false ) ) {
wp_send_json_error( 'verify_nonce: "bricks-nonce" is invalid.' );
}
// @since 1.5.4
if ( ! Capabilities::current_user_has_full_access() ) {
wp_send_json_error( 'verify_request: Sorry, you are not allowed to perform this action.' );
}
// Get latest settings
$settings = get_option( BRICKS_DB_GLOBAL_SETTINGS, [] );
$export_json = json_encode( $settings );
header( 'Content-Description: File Transfer' );
header( 'Content-type: application/txt' );
header( 'Content-Disposition: attachment; filename="bricks-settings-' . date( 'Y-m-d' ) . '.json"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate' );
header( 'Pragma: public' );
echo $export_json;
exit;
}
/**
* Save settings in WP dashboard on form 'save' submit
*
* @since 1.0
*/
public function save_settings() {
parse_str( $_POST['formData'], $settings );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => esc_html__( 'You don\'t have sufficient permission to save settings.', 'bricks' ) ] );
}
$old_settings = Database::$global_settings;
$new_settings = [];
// If execute code is disabled, remove any execute capability that might be set
if ( isset( $settings['executeCodeDisabled'] ) ) {
unset( $settings['executeCodeCapabilities'] );
}
foreach ( $settings as $key => $value ) {
if ( $key === 'builderLocale' && empty( $value ) ) {
$value = 'en_US';
}
if ( $value == '' ) {
continue;
}
if ( $value === 'on' ) {
$value = true;
}
// Min. autosave interval: 15 seconds
if ( $key === 'builderAutosaveInterval' && intval( $value ) < 15 ) {
$value = 15;
}
if ( $key === 'builderCapabilities' ) {
Capabilities::save_builder_capabilities( $value );
// Don't save selected capabilities in Global Settings, but as user role capabilities
continue;
}
if ( $key === 'uploadSvgCapabilities' ) {
Capabilities::save_capabilities( Capabilities::UPLOAD_SVG, $value );
// Don't save selected capabilities in Global Settings, but as user role capabilities
continue;
}
if ( $key === 'executeCodeCapabilities' ) {
Capabilities::save_capabilities( Capabilities::EXECUTE_CODE, $value );
// Don't save selected capabilities in Global Settings, but as user role capabilities
continue;
}
// Enciphered API keys: Save old value
if ( is_string( $value ) && strpos( $value, 'xxxx' ) !== false ) {
$new_settings[ $key ] = $old_settings[ $key ];
} else {
// Preserve backslashes in custom code (@since 1.5.1)
$run_wp_slash = in_array( $key, [ 'customCss', 'customScriptsHeader', 'customScriptsBodyHeader', 'customScriptsBodyFooter' ] );
if ( $run_wp_slash ) {
// jQuery.serialize() adds the slash to single quote
$value = str_replace( "\'", "'", $value );
$value = wp_slash( $value );
}
$new_settings[ $key ] = $value;
}
}
if ( empty( $settings['uploadSvgCapabilities'] ) ) {
Capabilities::save_capabilities( Capabilities::UPLOAD_SVG );
}
if ( empty( $settings['executeCodeCapabilities'] ) ) {
Capabilities::save_capabilities( Capabilities::EXECUTE_CODE );
}
update_option( BRICKS_DB_GLOBAL_SETTINGS, $new_settings );
// Sync Mailchimp and Sendgrid lists (@since 1.0)
$mailchimp_lists = \Bricks\Integrations\Form\Actions\Mailchimp::sync_lists();
$sendgrid_lists = \Bricks\Integrations\Form\Actions\Sendgrid::sync_lists();
// Download remote templates from server and store as db option
Templates::get_remote_templates_data();
wp_send_json_success(
[
'new_settings' => $new_settings,
'mailchimp_lists' => $mailchimp_lists,
'sendgrid_lists' => $sendgrid_lists,
]
);
}
/**
* Reset settings in WP dashboard on form 'reset' submit
*
* @since 1.0
*/
public function reset_settings() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => esc_html__( 'You don\'t have sufficient permission to reset settings.', 'bricks' ) ] );
}
delete_option( BRICKS_DB_GLOBAL_SETTINGS );
delete_option( 'bricks_mailchimp_lists' );
delete_option( 'bricks_sendgrid_lists' );
self::set_default_settings();
Capabilities::set_defaults();
wp_send_json_success();
}
/**
* Template columns
*
* @since 1.0
*/
public function bricks_template_posts_columns( $columns ) {
$columns = [
'cb' => '<input type="checkbox" />',
'title' => esc_html__( 'Title', 'bricks' ),
'template_type' => esc_html__( 'Type', 'bricks' ),
'template_conditions' => esc_html__( 'Conditions', 'bricks' ),
BRICKS_DB_TEMPLATE_TAX_BUNDLE => '<a href="' . admin_url( 'edit-tags.php?taxonomy=' . BRICKS_DB_TEMPLATE_TAX_BUNDLE ) . '">' . esc_html__( 'Bundle', 'bricks' ) . '</a>',
BRICKS_DB_TEMPLATE_TAX_TAG => '<a href="' . admin_url( 'edit-tags.php?taxonomy=' . BRICKS_DB_TEMPLATE_TAX_TAG ) . '">' . esc_html__( 'Tags', 'bricks' ) . '</a>',
'shortcode' => esc_html__( 'Shortcode', 'bricks' ),
'author' => esc_html__( 'Author', 'bricks' ),
'date' => esc_html__( 'Date', 'bricks' ),
];
return $columns;
}
/**
* Template custom column
*
* @since 1.0
*/
public function bricks_template_posts_custom_column( $column, $post_id ) {
$template_type = get_post_meta( $post_id, BRICKS_DB_TEMPLATE_TYPE, true );
// Template conditions
if ( $column === 'template_conditions' ) {
$settings_template_controls = isset( Settings::$controls['template'] ) ? Settings::$controls['template']['controls'] : false;
$template_settings = Helpers::get_template_settings( $post_id );
$template_conditions = isset( $template_settings['templateConditions'] ) && is_array( $template_settings['templateConditions'] ) ? $template_settings['templateConditions'] : [];
// STEP: No template conditions found: Check for default template (by template type, must be published)
if ( ! count( $template_conditions ) && ! Database::get_setting( 'defaultTemplatesDisabled', false ) && get_post_status( $post_id ) === 'publish' ) {
// Check if template type in a default template type
if ( in_array( $template_type, Database::$default_template_types ) ) {
$default_condition = '';
switch ( $template_type ) {
case 'header':
case 'footer':
$default_condition = esc_html__( 'Entire website', 'bricks' );
break;
case 'archive':
$default_condition = esc_html__( 'All archives', 'bricks' );
break;
case 'search':
$default_condition = esc_html__( 'Search results', 'bricks' );
break;
case 'error':
$default_condition = esc_html__( 'Error page', 'bricks' );
break;
// WooCommerce
case 'wc_archive':
$default_condition = esc_html__( 'Product archive', 'bricks' );
break;
case 'wc_product':
$default_condition = esc_html__( 'Single product', 'bricks' );
break;
case 'wc_cart':
$default_condition = esc_html__( 'Cart', 'bricks' );
break;
case 'wc_cart_empty':
$default_condition = esc_html__( 'Empty cart', 'bricks' );
break;
case 'wc_form_checkout':
$default_condition = esc_html__( 'Checkout', 'bricks' );
break;
case 'wc_form_pay':
$default_condition = esc_html__( 'Pay', 'bricks' );
break;
case 'wc_thankyou':
$default_condition = esc_html__( 'Thank you', 'bricks' );
break;
case 'wc_order_receipt':
$default_condition = esc_html__( 'Order receipt', 'bricks' );
break;
}
if ( $default_condition ) {
echo esc_html__( 'Default', 'bricks' ) . ': ' . $default_condition;
}
return;
}
}
$conditions = [];
if ( count( $template_conditions ) ) {
foreach ( $template_conditions as $template_condition ) {
$sub_conditions = [];
$main_condition = '';
if ( isset( $template_condition['main'] ) ) {
$main_condition = $settings_template_controls['templateConditions']['fields']['main']['options'][ $template_condition['main'] ];
switch ( $template_condition['main'] ) {
case 'ids':
if ( isset( $template_condition['ids'] ) && is_array( $template_condition['ids'] ) ) {
foreach ( $template_condition['ids'] as $id ) {
$sub_conditions[] = get_the_title( $id );
}
}
break;
case 'postType':
if ( isset( $template_condition['postType'] ) && is_array( $template_condition['postType'] ) ) {
foreach ( $template_condition['postType'] as $post_type ) {
$post_type_object = get_post_type_object( $post_type );
if ( $post_type_object ) {
$sub_conditions[] = $post_type_object->labels->singular_name;
} else {
$sub_conditions[] = ucfirst( $post_type );
}
}
}
break;
case 'archiveType':
if ( isset( $template_condition['archiveType'] ) && is_array( $template_condition['archiveType'] ) ) {
foreach ( $template_condition['archiveType'] as $archive_type ) {
$sub_conditions[] = $settings_template_controls['templateConditions']['fields']['archiveType']['options'][ $archive_type ];
}
}
break;
case 'terms':
if ( isset( $template_condition['terms'] ) && is_array( $template_condition['terms'] ) ) {
foreach ( $template_condition['terms'] as $term_parts ) {
$term_parts = explode( '::', $term_parts );
$taxonomy = $term_parts[0];
$term_id = $term_parts[1];
$term = get_term_by( 'id', $term_id, $taxonomy );
if ( gettype( $term ) === 'object' ) {
$sub_conditions[] = $term->name;
}
}
}
break;
}
} else {
echo '-';
}
$main_condition = isset( $template_condition['exclude'] ) ? esc_html__( 'Exclude', 'bricks' ) . ': ' . $main_condition : $main_condition;
if ( count( $sub_conditions ) ) {
$conditions[] = $main_condition . ' (' . join( ', ', $sub_conditions ) . ')';
} else {
$conditions[] = $main_condition;
}
}
} else {
echo '-';
}
if ( count( $conditions ) ) {
echo '<ul>';
foreach ( $conditions as $condition ) {
echo '<li>' . $condition . '</li>';
}
echo '</ul>';
}
}
// Template type
elseif ( $column === 'template_type' ) {
$template_types = Setup::$control_options['templateTypes'];
echo array_key_exists( $template_type, $template_types ) ? $template_types[ $template_type ] : '-';
}
// Template bundle
elseif ( $column === BRICKS_DB_TEMPLATE_TAX_BUNDLE ) {
$template_bundles = get_the_terms( $post_id, BRICKS_DB_TEMPLATE_TAX_BUNDLE );
if ( is_array( $template_bundles ) ) {
$bundle_url = [];
foreach ( $template_bundles as $bundle ) {
$bundle_list_url = admin_url( 'edit.php?post_type=' . BRICKS_DB_TEMPLATE_SLUG . '&template_bundle=' . $bundle->slug );
$bundle_edit_url = get_edit_tag_link( $bundle->term_id, BRICKS_DB_TEMPLATE_TAX_BUNDLE );
$bundle_url[] = '<a href="' . esc_url( $bundle_list_url ) . '">' . $bundle->name . '</a> (<a href="' . $bundle_edit_url . '">' . esc_html( 'edit', 'bricks' ) . '</a>)';
}
echo join( ', ', $bundle_url );
} else {
echo '-';
}
}
// Template tag
elseif ( $column === BRICKS_DB_TEMPLATE_TAX_TAG ) {
$template_tags = get_the_terms( $post_id, BRICKS_DB_TEMPLATE_TAX_TAG );
if ( is_array( $template_tags ) ) {
$tag_url = [];
foreach ( $template_tags as $tag ) {
$tag_list_url = admin_url( 'edit.php?post_type=' . BRICKS_DB_TEMPLATE_SLUG . '&template_tag=' . $tag->slug );
$tag_edit_url = get_edit_tag_link( $tag->term_id, BRICKS_DB_TEMPLATE_TAX_TAG );
$tag_url[] = '<a href="' . esc_url( $tag_list_url ) . '">' . $tag->name . '</a> (<a href="' . $tag_edit_url . '">' . esc_html( 'edit', 'bricks' ) . '</a>)';
}
echo join( ', ', $tag_url );
} else {
echo '-';
}
}
// Template shortcode
elseif ( $column === 'shortcode' ) {
$shortcode = "[bricks_template id=\"$post_id\"]";
echo '<input type="text" size="' . strlen( $shortcode ) . '" class="bricks-copy-to-clipboard" readonly data-success="' . esc_html__( 'Copied to clipboard', 'bricks' ) . '" value="' . esc_attr( $shortcode ) . '">';
}
return $column;
}
/**
* Set default settings
*
* @since 1.0
*/
public static function set_default_settings() {
add_option(
BRICKS_DB_GLOBAL_SETTINGS,
[
'postTypes' => [ 'page' ],
'builderMode' => 'dark',
'builderToolbarLogoLink' => 'current',
]
);
}
public function gutenberg_scripts() {
if ( Helpers::is_post_type_supported() && Capabilities::current_user_can_use_builder() ) {
wp_enqueue_script( 'bricks-gutenberg', BRICKS_URL_ASSETS . 'js/gutenberg.min.js', [ 'jquery' ], filemtime( BRICKS_PATH_ASSETS . 'js/gutenberg.min.js' ), true );
}
}
/**
* Admin scripts and styles
*
* @since 1.0
*/
public function admin_enqueue_scripts() {
wp_enqueue_style( 'bricks-admin', BRICKS_URL_ASSETS . 'css/admin.min.css', [], filemtime( BRICKS_PATH_ASSETS . 'css/admin.min.css' ) );
if ( is_rtl() ) {
wp_enqueue_style( 'bricks-admin-rtl', BRICKS_URL_ASSETS . 'css/admin-rtl.min.css', [ 'bricks-admin' ], filemtime( BRICKS_PATH_ASSETS . 'css/admin-rtl.min.css' ) );
}
wp_enqueue_script( 'bricks-admin', BRICKS_URL_ASSETS . 'js/admin.min.js', [ 'jquery' ], filemtime( BRICKS_PATH_ASSETS . 'js/admin.min.js' ), true );
wp_localize_script(
'bricks-admin',
'bricksData',
[
'title' => BRICKS_NAME,
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'postId' => get_the_ID(),
'nonce' => wp_create_nonce( 'bricks-nonce' ),
'currentScreen' => get_current_screen(),
'cofirmResetSettings' => esc_html__( 'You are about to reset all Bricks global settings. Do you wish to proceed?', 'bricks' ),
'deleteBricksDataUrl' => Helpers::delete_bricks_data_by_post_id(),
]
);
}
/**
* Admin menu
*
* @since 1.0
*/
public function admin_menu() {
// Return: Current user has no access to Bricks
if ( Capabilities::current_user_has_no_access() ) {
return;
}
$menu_icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iMzVweCIgaGVpZ2h0PSI0NXB4IiB2aWV3Qm94PSIwIDAgMzUgNDUiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU5LjEgKDg2MTQ0KSAtIGh0dHBzOi8vc2tldGNoLmNvbSAtLT4KICAgIDx0aXRsZT5iPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9IkxvZ29zLC1GYXZpY29uIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iRmF2aWNvbi0oNjR4NjQpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTYuMDAwMDAwLCAtMTEuMDAwMDAwKSIgZmlsbD0iIzIxMjEyMSIgZmlsbC1ydWxlPSJub256ZXJvIj4KICAgICAgICAgICAgPHBhdGggZD0iTTI1LjE4NzUsMTEuMzQzNzUgTDI1LjkzNzUsMTEuODEyNSBMMjUuOTM3NSwyNC44NDM3NSBDMjguNTgzMzQ2NiwyMy4wOTM3NDEzIDMxLjUxMDQwMDYsMjIuMjE4NzUgMzQuNzE4NzUsMjIuMjE4NzUgQzM5LjM0Mzc3MzEsMjIuMjE4NzUgNDMuMTc3MDY4MSwyMy44MzMzMTcyIDQ2LjIxODc1LDI3LjA2MjUgQzQ5LjIxODc2NSwzMC4yOTE2ODI4IDUwLjcxODc1LDM0LjI3MDgwOTcgNTAuNzE4NzUsMzkgQzUwLjcxODc1LDQzLjc1MDAyMzcgNDkuMjA4MzQ4NCw0Ny43MjkxNTA2IDQ2LjE4NzUsNTAuOTM3NSBDNDMuMTQ1ODE4MSw1NC4xNjY2ODI4IDM5LjMyMjkzOTcsNTUuNzgxMjUgMzQuNzE4NzUsNTUuNzgxMjUgQzMwLjY5Nzg5NjYsNTUuNzgxMjUgMjcuMjYwNDMwOSw1NC4zNDM3NjQ0IDI0LjQwNjI1LDUxLjQ2ODc1IEwyNC40MDYyNSw1NSBMMTYuMDMxMjUsNTUgTDE2LjAzMTI1LDEyLjM3NSBMMjUuMTg3NSwxMS4zNDM3NSBaIE0zMy4xMjUsMzAuNjg3NSBDMzAuOTE2NjU1NiwzMC42ODc1IDI5LjA3MjkyNDEsMzEuNDM3NDkyNSAyNy41OTM3NSwzMi45Mzc1IEMyNi4xMTQ1NzU5LDM0LjQ3OTE3NDQgMjUuMzc1LDM2LjQ5OTk4NzUgMjUuMzc1LDM5IEMyNS4zNzUsNDEuNTAwMDEyNSAyNi4xMTQ1NzU5LDQzLjUxMDQwOTEgMjcuNTkzNzUsNDUuMDMxMjUgQzI5LjA1MjA5MDYsNDYuNTUyMDkwOSAzMC44OTU4MjIyLDQ3LjMxMjUgMzMuMTI1LDQ3LjMxMjUgQzM1LjQ3OTE3ODQsNDcuMzEyNSAzNy4zODU0MDk0LDQ2LjUyMDg0MTMgMzguODQzNzUsNDQuOTM3NSBDNDAuMjgxMjU3Miw0My4zNzQ5OTIyIDQxLDQxLjM5NTg0NTMgNDEsMzkgQzQxLDM2LjYwNDE1NDcgNDAuMjcwODQwNiwzNC42MTQ1OTEzIDM4LjgxMjUsMzMuMDMxMjUgQzM3LjM1NDE1OTQsMzEuNDY4NzQyMiAzNS40NTgzNDUsMzAuNjg3NSAzMy4xMjUsMzAuNjg3NSBaIiBpZD0iYiI+PC9wYXRoPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+';
add_menu_page(
BRICKS_NAME,
BRICKS_NAME,
self::EDITING_CAP,
'bricks',
[ $this, 'admin_screen_getting_started' ],
$menu_icon,
// 'dashicons-editor-bold',
// BRICKS_URL_ASSETS . 'images/bricks-favicon-b.svg',
2
);
add_submenu_page(
'bricks',
esc_html__( 'Getting Started', 'bricks' ),
esc_html__( 'Getting Started', 'bricks' ),
self::EDITING_CAP,
'bricks',
[ $this, 'admin_screen_getting_started' ]
);
add_submenu_page(
'bricks',
esc_html__( 'Templates', 'bricks' ),
esc_html__( 'Templates', 'bricks' ),
self::EDITING_CAP,
'edit.php?post_type=' . BRICKS_DB_TEMPLATE_SLUG
);
add_submenu_page(
'bricks',
esc_html__( 'Settings', 'bricks' ),
esc_html__( 'Settings', 'bricks' ),
'manage_options',
'bricks-settings',
[ $this, 'admin_screen_settings' ]
);
add_submenu_page(
'bricks',
esc_html__( 'Custom Fonts', 'bricks' ),
esc_html__( 'Custom Fonts', 'bricks' ),
'manage_options',
'edit.php?post_type=' . BRICKS_DB_CUSTOM_FONTS
);
add_submenu_page(
'bricks',
esc_html__( 'Sidebars', 'bricks' ),
esc_html__( 'Sidebars', 'bricks' ),
'manage_options',
'bricks-sidebars',
[ $this, 'admin_screen_sidebars' ]
);
add_submenu_page(
'bricks',
esc_html__( 'System Information', 'bricks' ),
esc_html__( 'System Information', 'bricks' ),
'manage_options',
'bricks-system-information',
[ $this, 'admin_screen_system_information' ]
);
add_submenu_page(
'bricks',
esc_html__( 'License', 'bricks' ),
esc_html__( 'License', 'bricks' ),
'manage_options',
'bricks-license',
[ $this, 'admin_screen_license' ]
);
}
public function admin_screen_getting_started() {
require_once 'admin/admin-screen-getting-started.php';
}
public function admin_screen_settings() {
require_once 'admin/admin-screen-settings.php';
}
public function admin_screen_sidebars() {
require_once 'admin/admin-screen-sidebars.php';
}
public function admin_screen_system_information() {
require_once 'admin/admin-screen-system-information.php';
}
public function admin_screen_license() {
require_once 'admin/admin-screen-license.php';
}
/**
* Admin notice: Show regenerate CSS files notification after Bricks theme update
*
* @since 1.3.7
*/
public static function admin_notice_regenerate_css_files() {
// Show update & CSS files regeneration admin notice ONCE after theme update
if ( get_option( BRICKS_CSS_FILES_ADMIN_NOTICE ) ) {
$text = '<p>' . esc_html__( 'You are now running the latest version of Bricks', 'bricks' ) . ': ' . BRICKS_VERSION . ' 🥳</p>';
$text .= '<p>' . esc_html__( 'Your Bricks CSS files were automatically generated in the background.', 'bricks' ) . '</p>';
$text .= '<a class="button button-primary" href="' . admin_url( 'admin.php?page=bricks-settings#tab-performance' ) . '">' . esc_html__( 'Manually regenerate CSS files', 'bricks' ) . '</a>';
$text .= '<a class="button" href="https://bricksbuilder.io/changelog/#v' . BRICKS_VERSION . '" target="_blank" style="margin: 4px">' . esc_html__( 'View changelog', 'bricks' ) . '</a>';
echo wp_kses_post( sprintf( '<div class="notice notice-info is-dismissible">%s</div>', wpautop( $text ) ) );
// Remove admin notice option entry to not show it again
delete_option( BRICKS_CSS_FILES_ADMIN_NOTICE );
// Fallback: Regenerate CSS files now (@since 1.8.1)
if ( Database::get_setting( 'cssLoading' ) === 'file' ) {
Assets_Files::regenerate_css_files();
// NOTE: Not in use. Requires WP cron & not needed here anymore as we already run the updated theme version code
// Assets_Files::schedule_css_file_regeneration();
}
}
}
/**
* Admin notices
*
* @since 1.0
*/
public function admin_notices() {
if ( empty( $_GET['bricks_notice'] ) ) {
return;
}
$type = 'warning';
$text = '';
switch ( $_GET['bricks_notice'] ) {
case 'settings_saved':
// Bricks settings saved
$text = esc_html__( 'Settings saved', 'bricks' ) . '.';
$type = 'success';
break;
case 'settings_resetted':
// Bricks settings resetted
$text = esc_html__( 'Settings resetted', 'bricks' ) . '.';
$type = 'success';
break;
case 'error_role_manager':
// User role not allowed to use builder
$user = wp_get_current_user();
$role = isset( $user->roles[0] ) ? $user->roles[0] : '';
$text = sprintf( esc_html__( 'Your user role "%s" is not allowed to edit with Bricks. Please get in touch with the site admin to change it.', 'bricks' ), $role );
break;
case 'error_post_type':
// Post type is not enabled for Bricks
$post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : '';
$text = sprintf( esc_html__( 'Bricks is not enabled for post type "%s". Go to "Bricks > Settings" to enable this post type.', 'bricks' ), $post_type );
break;
case 'post_meta_deleted':
$text = sprintf( esc_html__( 'Bricks data for "%s" deleted.', 'bricks' ), get_the_title() );
$type = 'success';
break;
}
$html = sprintf( '<div class="notice notice-' . sanitize_html_class( $type, 'warning' ) . ' is-dismissible">%s</div>', wpautop( $text ) );
// echo wp_kses_post( $html );
echo self::admin_notice_html( $type, $text );
}
public static function admin_notice_html( $type, $text, $dismissible = true ) {
$classes = [ 'notice', "notice-$type" ];
if ( $dismissible ) {
$classes[] = 'is-dismissible';
}
return wp_kses_post( sprintf( '<div class="' . implode( ' ', $classes ) . '">%s</div>', wpautop( $text ) ) );
}
/**
* Add custom post state: "Bricks"
*
* If post has last been saved with Bricks (check post meta value: '_bricks_editor_mode')
*
* @param array $post_states Array of post states.
* @param \WP_Post $post Current post object.
*
* @since 1.0
*/
public function add_post_state( $post_states, $post ) {
if (
! Helpers::is_post_type_supported() ||
! Capabilities::current_user_can_use_builder( $post->ID ) ||
Helpers::get_editor_mode( $post->ID ) === 'wordpress'
) {
return $post_states;
}
$post_states['bricks'] = BRICKS_NAME;
$data_type = 'content';
$is_template = get_post_type( $post->ID ) === BRICKS_DB_TEMPLATE_SLUG;
if ( $is_template ) {
$template_type = Templates::get_template_type( $post->ID );
if ( $template_type === 'header' ) {
$data_type = 'header';
} elseif ( $template_type === 'footer' ) {
$data_type = 'footer';
}
}
// Checks for new data structure
$has_container_data = get_post_meta( $post->ID, "_bricks_page_{$data_type}_2", true );
// No Bricks container data: Remove 'Bricks' label
if ( ! $has_container_data && ! $is_template ) {
unset( $post_states['bricks'] );
}
return $post_states;
}
/**
* Add editor body class 'active'
*
* @since 1.0
*
* @return string
*/
public function admin_body_class( $classes ) {
global $pagenow;
if ( ! in_array( $pagenow, [ 'post.php', 'post-new.php' ] ) ) {
return $classes;
}
$editor_mode = Helpers::get_editor_mode( get_the_ID() );
if ( ! empty( $editor_mode ) ) {
$classes .= ' ' . $editor_mode . '-editor-active';
}
return $classes;
}
/**
* Add custom image sizes to WordPress media library in admin area
*
* Also used to build dropdown of control 'images' for single image element.
*
* @since 1.0
*/
public function image_size_names_choose( $default_sizes ) {
global $_wp_additional_image_sizes;
$custom_image_sizes = [];
foreach ( $_wp_additional_image_sizes as $key => $value ) {
$key_array = explode( '_', $key );
$capitalized_array = [];
foreach ( $key_array as $string ) {
array_push( $capitalized_array, ucfirst( $string ) );
}
$custom_image_sizes[ $key ] = join( ' ', $capitalized_array );
}
return array_merge( $default_sizes, $custom_image_sizes );
}
/**
* Make sure 'editor_mode' URL param is not removed from admin URL
*/
public function admin_url( $link ) {
if ( isset( $_REQUEST['editor_mode'] ) && ! empty( $_REQUEST['editor_mode'] ) ) {
return add_query_arg(
[
'editor_mode' => $_REQUEST['editor_mode']
],
$link
);
}
return $link;
}
/**
* Save Editor mode based on the admin bar links
*
* @see Setup->admin_bar_menu()
*
* @since 1.3.7
*/
public function save_editor_mode() {
if ( empty( $_GET['editor_mode'] ) || ! isset( $_GET['action'] ) || empty( $_GET['post'] ) || ! isset( $_GET['_bricksmode'] ) ) {
return;
}
if ( ! wp_verify_nonce( $_GET['_bricksmode'], '_bricks_editor_mode_nonce' ) ) {
return;
}
update_post_meta( $_GET['post'], BRICKS_DB_EDITOR_MODE, $_GET['editor_mode'] );
}
/**
* Builder tab HTML (toggle via builder tab)
*
* @since 1.0
*
* @return string
*/
public function builder_tab_html() {
// Show builder-related HTML only if post type and user role is enabled for builder
if ( ! Helpers::is_post_type_supported() || ! Capabilities::current_user_can_use_builder() ) {
return;
}
// Delete post meta: content and editor mode
if ( isset( $_GET['bricks_delete_post_meta'] ) ) {
delete_post_meta( $_GET['bricks_delete_post_meta'], BRICKS_DB_PAGE_HEADER );
delete_post_meta( $_GET['bricks_delete_post_meta'], BRICKS_DB_PAGE_CONTENT );
delete_post_meta( $_GET['bricks_delete_post_meta'], BRICKS_DB_PAGE_FOOTER );
delete_post_meta( $_GET['bricks_delete_post_meta'], BRICKS_DB_PAGE_SETTINGS );
delete_post_meta( $_GET['bricks_delete_post_meta'], BRICKS_DB_EDITOR_MODE );
delete_post_meta( $_GET['bricks_delete_post_meta'], BRICKS_DB_TEMPLATE_TYPE );
}
// Get editor mode
$editor_mode = Helpers::get_editor_mode( get_the_ID() );
?>
<div id="bricks-editor" class="bricks-editor postarea wp-editor-expand">
<?php wp_nonce_field( 'editor_mode', '_bricks_editor_mode_nonce' ); ?>
<input type="hidden" id="bricks-editor-mode" name="_bricks_editor_mode" value="<?php echo esc_attr( $editor_mode ); ?>" />
<div class="wp-core-ui wp-editor-wrap bricks-active">
<?php if ( get_post_type() !== BRICKS_DB_TEMPLATE_SLUG ) { ?>
<div class="wp-editor-tools">
<div class="wp-editor-tabs">
<button type="button" id="content-tmce" class="wp-switch-editor switch-tmce"><?php esc_html_e( 'Visual', 'bricks' ); ?></button>
<button type="button" id="content-html" class="wp-switch-editor switch-html"><?php esc_html_e( 'Text', 'bricks' ); ?></button>
<button type="button" id="content-bricks" class="wp-switch-editor switch-bricks"><?php echo BRICKS_NAME; ?></button>
</div>
</div>
<?php } ?>
<div class="wp-editor-container">
<p><a href="<?php echo Helpers::get_builder_edit_link( get_the_ID() ); ?>" class="button button-primary button-hero"><?php esc_html_e( 'Edit with Bricks', 'bricks' ); ?></a></p>
<?php if ( Database::get_setting( 'deleteBricksData', false ) ) { ?>
<p><a href="<?php echo esc_url( Helpers::delete_bricks_data_by_post_id() ); ?>" class="bricks-delete-post-meta button" onclick="return confirm('<?php echo sprintf( esc_html__( 'Are you sure you want to delete the Bricks-generated data for this %s?', 'bricks' ), get_post_type() ); ?>')"><?php esc_html_e( 'Delete Bricks data', 'bricks' ); ?></a></p>
<?php } ?>
</div>
</div>
</div>
<?php
}
/**
* "Edit with Bricks" link for post type 'page', 'post' and all other CPTs
*
* @since 1.0
*/
public function row_actions( $actions, $post ) {
if ( Helpers::is_post_type_supported() && Capabilities::current_user_can_use_builder( $post->ID ) ) {
// Export template
if ( get_post_type() === BRICKS_DB_TEMPLATE_SLUG ) {
$export_template_url = admin_url( 'admin-ajax.php' );
$export_template_url = add_query_arg(
[
'action' => 'bricks_export_template',
'nonce' => wp_create_nonce( 'bricks-nonce' ),
'templateId' => get_the_ID(),
],
$export_template_url
);
$actions['export_template'] = sprintf(
'<a href="%s">%s</a>',
$export_template_url,
esc_html__( 'Export Template', 'bricks' )
);
}
// Edit with Bricks
$actions['edit_with_bricks'] = sprintf(
'<a href="%s">%s</a>',
Helpers::get_builder_edit_link( $post->ID ),
esc_html__( 'Edit with Bricks', 'bricks' )
);
}
return $actions;
}
}