ction get_node_template_root( $type = '', $nodes = array() )
{
foreach ( $nodes as $node ) {
if ( $type == $node->type ) {
return $node;
}
}
return false;
}
/**
* Uses a node template ID to retrieve its post ID.
*
* @since 1.6.3
* @param string $template_id The node template ID as stored in the template's post meta.
* @return int
*/
static public function get_node_template_post_id( $template_id )
{
if ( isset( self::$node_template_post_ids[ $template_id ] ) ) {
return self::$node_template_post_ids[ $template_id ];
}
else {
$posts = get_posts( array(
'post_type' => 'fl-builder-template',
'post_status' => array( 'any', 'trash' ),
'posts_per_page' => '-1',
'meta_key' => '_fl_builder_template_id',
'meta_value' => $template_id
) );
if ( 0 === count( $posts ) ) {
return false;
}
self::$node_template_post_ids[ $template_id ] = $posts[ 0 ]->ID;
return $posts[ 0 ]->ID;
}
}
/**
* Returns the edit URL for a node template.
*
* @since 1.6.3
* @param string $template_id The node template ID as stored in the template's post meta.
* @return string
*/
static public function get_node_template_edit_url( $template_id )
{
return self::get_edit_url( self::get_node_template_post_id( $template_id ) );
}
/**
* Returns an array of posts that have the global node template
* with the specified ID.
*
* @since 1.6.3
* @param int $post_id The post ID of the global node template.
* @return array
*/
static public function get_posts_with_global_node_template( $post_id = false )
{
$posts = array();
if ( self::is_post_global_node_template( $post_id ) ) {
$template_id = get_post_meta( $post_id, '_fl_builder_template_id', true );
$query = new WP_Query( array(
'meta_query' => array(
'relation' => 'OR',
array(
'key' => '_fl_builder_data',
'value' => $template_id,
'compare' => 'LIKE'
),
array(
'key' => '_fl_builder_draft',
'value' => $template_id,
'compare' => 'LIKE'
)
),
'post_type' => 'any',
'post_status' => 'any',
'post__not_in' => array( $post_id )
) );
$posts = $query->posts;
}
return $posts;
}
/**
* Saves a node template.
*
* @since 1.6.3
* @param string $template_node_id The ID of the node to save as a template.
* @param string $settings The settings for this template.
* @return void
*/
static public function save_node_template( $template_node_id, $settings )
{
$root_node = self::get_node( $template_node_id );
$nodes = self::get_nested_nodes( $template_node_id );
$template_id = self::generate_node_id();
$original_parent = $root_node->parent;
$original_position = $root_node->position;
// Save the node template post.
$post_id = wp_insert_post( array(
'post_title' => $settings['name'],
'post_type' => 'fl-builder-template',
'post_status' => 'publish',
'ping_status' => 'closed',
'comment_status' => 'closed'
) );
// Set the template type.
wp_set_post_terms( $post_id, $root_node->type, 'fl-builder-template-type' );
// Reset the root node's position.
$root_node->position = 0;
// Add the root node to the nodes array.
$nodes[ $root_node->node ] = $root_node;
// Generate new node ids.
$nodes = self::generate_new_node_ids( $nodes );
// Get the root node from the template data since its ID changed.
$root_node = self::get_node_template_root( $root_node->type, $nodes );
// Add the template ID and template node ID for global templates.
if ( $settings['global'] ) {
foreach ( $nodes as $node_id => $node ) {
$nodes[ $node_id ]->template_id = $template_id;
$nodes[ $node_id ]->template_node_id = $node_id;
if ( $node_id == $root_node->node ) {
$nodes[ $node_id ]->template_root_node = true;
}
else if ( isset( $nodes[ $node_id ]->template_root_node ) ) {
unset( $nodes[ $node_id ]->template_root_node );
}
}
}
// We need to remove the template ID and template node ID for standard templates.
else {
foreach ( $nodes as $node_id => $node ) {
if ( isset( $nodes[ $node_id ]->template_id ) ) {
unset( $nodes[ $node_id ]->template_id );
}
if ( isset( $nodes[ $node_id ]->template_node_id ) ) {
unset( $nodes[ $node_id ]->template_node_id );
}
if ( isset( $nodes[ $node_id ]->template_root_node ) ) {
unset( $nodes[ $node_id ]->template_root_node );
}
}
}
// Save the template layout data.
self::update_layout_data( $nodes, 'published', $post_id );
self::update_layout_data( $nodes, 'draft', $post_id );
// Enable the builder for this template.
update_post_meta( $post_id, '_fl_builder_enabled', true );
// Add the template ID post meta. We use a custom ID for node
// templates in case templates are imported since their WordPress
// IDs will change, breaking global templates.
update_post_meta( $post_id, '_fl_builder_template_id', $template_id );
// Add the template global flag post meta.
update_post_meta( $post_id, '_fl_builder_template_global', $settings['global'] );
// Delete the existing node and apply the template for global templates.
if ( $settings['global'] ) {
// Delete the existing node.
self::delete_node( $template_node_id );
// Apply the global template.
$root_node = self::apply_node_template( $template_id, $original_parent, $original_position );
}
// Return an array of template settings.
return array(
'id' => $template_id,
'global' => $settings['global'] ? true : false,
'link' => add_query_arg( 'fl_builder', '', get_permalink( $post_id ) ),
'name' => $settings['name'],
'type' => $root_node->type,
'layout' => $settings['global'] ? FLBuilderAJAXLayout::render( $root_node->node, $template_node_id ) : null
);
}
/**
* Sets the default type for a node template when created in wp-admin.
*
* @since 1.6.3
* @param int $post_ID The post ID for the template.
* @param object $post The post object for the template.
* @param bool $update Whether this is a new post or an update.
* @return void
*/
static public function set_node_template_default_type( $post_id, $post, $update )
{
if ( $update || 'fl-builder-template' != $post->post_type ) {
return;
}
$type = wp_get_post_terms( $post_id, 'fl-builder-template-type' );
if ( 0 === count( $type ) ) {
wp_set_post_terms( $post_id, 'layout', 'fl-builder-template-type' );
}
}
/**
* Deletes a node template via AJAX.
*
* @since 1.6.3
* @param string $template_id The ID of node template to delete.
* @return void
*/
static public function delete_node_template( $template_id )
{
// Make sure we have a template ID.
if ( ! isset( $template_id ) ) {
return;
}
// Get the post ID for the template.
$template_post_id = self::get_node_template_post_id( $template_id );
// Bail if we don't have a post ID.
if ( ! $template_post_id ) {
return;
}
// Unlink if this is a global template.
self::unlink_global_node_template_from_all_posts( $template_post_id );
// Delete the template post.
wp_delete_post( $template_post_id, true );
}
/**
* Unlinks all instances of a global node template in all posts.
*
* @since 1.6.3
* @param int $template_post_id The post ID of the template to unlink.
* @return void
*/
static public function unlink_global_node_template_from_all_posts( $template_post_id )
{
if ( self::is_post_global_node_template( $template_post_id ) ) {
$posts = self::get_posts_with_global_node_template( $template_post_id );
$template_id = get_post_meta( $template_post_id, '_fl_builder_template_id', true );
foreach ( $posts as $post ) {
self::unlink_global_node_template_from_post( 'published', $post->ID, $template_post_id, $template_id );
self::unlink_global_node_template_from_post( 'draft', $post->ID, $template_post_id, $template_id );
self::delete_all_asset_cache( $post->ID );
}
}
}
/**
* Unlinks all instances of a global node template from a post's
* layout data with the specified status. Since only the root node
* of a global template is saved to a posts layout data, the child
* nodes will be saved to the post when the global template is unlinked.
*
* @since 1.6.3
* @param string $status The status of the layout data. Either draft or published.
* @param int $post_id The ID of the post to unlink from.
* @param string $template_post_id The post ID of the template to unlink from the layout data.
* @param string $template_id The ID of the template to unlink from the layout data.
* @return void
*/
static public function unlink_global_node_template_from_post( $status, $post_id, $template_post_id, $template_id )
{
$template_data = self::get_layout_data( $status, $template_post_id );
$layout_data = self::get_layout_data( $status, $post_id );
$update = false;
// Loop through the layout data.
foreach ( $layout_data as $node_id => $node ) {
// Check to see if this is the global template node to unlink.
if ( isset( $node->template_id ) && $node->template_id == $template_id ) {
// Generate new node ids for the template data.
$new_data = self::generate_new_node_ids( $template_data );
// Get the root node from the template data.
$root_node = self::get_node_template_root( $node->type, $new_data );
// Remove the root node from the template data since it's already in the layout.
unset( $new_data[ $root_node->node ] );
// Update the settings for the root node in this layout.
$layout_data[ $node_id ]->settings = $root_node->settings;
// Update children with the new parent node ID.
foreach ( $new_data as $i => $n ) {
if ( $n->parent == $root_node->node ) {
$new_data[ $i ]->parent = $node->node;
}
}
// Add the template data to the layout data.
$layout_data = array_merge( $layout_data, $new_data );
// Set the update flag.
$update = true;
}
}
// Only update if we need to.
if ( $update ) {
// Remove template info from the layout data.
foreach ( $layout_data as $node_id => $node ) {
unset( $layout_data[ $node_id ]->template_id );
unset( $layout_data[ $node_id ]->template_post_id );
unset( $layout_data[ $node_id ]->template_root_node );
}
// Update the layout data.
self::update_layout_data( $layout_data, $status, $post_id );
}
}
/**
* Deletes all instances of a global node template from all posts.
*
* @since 1.6.3
* @param int $template_post_id The post ID of the template to delete.
* @return void
*/
static public function delete_global_node_template_from_all_posts( $template_post_id )
{
if ( self::is_post_global_node_template( $template_post_id ) ) {
$posts = self::get_posts_with_global_node_template( $template_post_id );
$template_id = get_post_meta( $template_post_id, '_fl_builder_template_id', true );
foreach ( $posts as $post ) {
self::delete_global_node_template_from_post( 'published', $post->ID, $template_id );
self::delete_global_node_template_from_post( 'draft', $post->ID, $template_id );
self::delete_all_asset_cache( $post->ID );
}
}
}
/**
* Deletes all instances of a global node template from a post's
* layout data with the specified status.
*
* @since 1.6.3
* @param string $status The status of the layout data. Either draft or published.
* @param int $post_id The ID of the post to delete from.
* @param string $template_id The ID of the template to delete from the layout data.
* @return void
*/
static public function delete_global_node_template_from_post( $status, $post_id, $template_id )
{
$layout_data = self::get_layout_data( $status, $post_id );
$update = false;
// Loop through the nodes.
foreach ( $layout_data as $node_id => $node ) {
$siblings = array();
$position = 0;
// Check to see if this is the global template node to delete.
if ( isset( $node->template_id ) && $node->template_id == $template_id ) {
// Unset this node in the layout data.
unset( $layout_data[ $node_id ] );
// Find sibiling nodes to update their position.
foreach ( $layout_data as $i => $n ) {
if ( $n->parent == $node->parent ) {
$siblings[ $i ] = $n;
}
}
// Sort the sibiling nodes by position.
uasort( $siblings, array( 'FLBuilderModel', 'order_nodes' ) );
// Update sibiling node positions.
foreach ( $siblings as $i => $n ) {
$layout_data[ $i ]->position = $position;
$position++;
}
// Set the update flag.
$update = true;
}
}
// Only update if we need to.
if ( $update ) {
self::update_layout_data( $layout_data, $status, $post_id );
}
}
/**
* Applies a node template to the current layout.
*
* @since 1.6.3
* @param int $template_id The node template ID.
* @param string $parent_id The new parent node ID for the template.
* @param int $position The position of the template within the layout.
* @param object $template Optional. Template data to use instead of pulling it with the template ID.
* @return void
*/
static public function apply_node_template( $template_id = null, $parent_id = null, $position = 0, $template = null )
{
$parent = $parent_id == 0 ? null : self::get_node( $parent_id );
$template_post_id = self::get_node_template_post_id( $template_id );
// Allow extensions to hook into applying a node template.
$override = apply_filters( 'fl_builder_override_apply_node_template', false, array(
'template_id' => $template_id,
'parent_id' => $parent_id,
'position' => $position,
'template' => $template,
'template_post_id' => $template_post_id
) );
// Return if we got an override from the filter.
if ( $override ) {
return $override;
}
// Get the template data from $template if we have it.
if ( is_object( $template ) ) {
$template_data = $template->nodes;
$template_settings = $template->settings;
$type = $template->type;
$global = $template->global;
}
// Get the template data.
else {
$template_data = self::get_layout_data( 'published', $template_post_id );
$template_settings = self::get_layout_settings( 'published', $template_post_id );
$type = self::get_user_template_type( $template_post_id );
$global = get_post_meta( $template_post_id, '_fl_builder_template_global', true );
}
// Generate new node ids.
$template_data = self::generate_new_node_ids( $template_data );
// Get the root node from the template data.
$root_node = self::get_node_template_root( $type, $template_data );
// Add a new parent for module node templates if needed.
if ( 'module' == $root_node->type && ( ! $parent || 'row' == $parent->type || 'column-group' == $parent->type ) ) {
$parent_id = self::add_module_parent( $parent_id, $position );
$position = null;
}
// Update the root node's parent.
$template_data[ $root_node->node ]->parent = ! $parent_id ? null : $parent_id;
// Get the layout data and settings.
$layout_data = self::get_layout_data( 'draft' );
$layout_settings = self::get_layout_settings( 'draft' );
// Only merge the root node for global templates.
if ( $global ) {
$layout_data[ $root_node->node ] = $template_data[ $root_node->node ];
}
// Merge all template data and settings for standard templates.
else {
// Merge template data.
foreach ( $template_data as $node_id => $node ) {
unset( $template_data[ $node_id ]->template_id );
unset( $template_data[ $node_id ]->template_post_id );
unset( $template_data[ $node_id ]->template_root_node );
}
$layout_data = array_merge( $layout_data, $template_data );
// Merge template settings.
$layout_settings = self::merge_layout_settings( $layout_settings, $template_settings );
}
// Update the layout data and settings.
self::update_layout_data( $layout_data );
self::update_layout_settings( $layout_settings );
// Reorder the main template node.
if ( null !== $position ) {
self::reorder_node( $root_node->node, $position );
}
// Delete old asset cache.
self::delete_asset_cache();
// Return the root node.
if ( 'module' == $root_node->type ) {
return self::get_module( $root_node->node );
}
else {
return $root_node;
}
}
/**
* Registers a template data file with the builder.
*
* @since 1.8
* @param sting $path The directory path to the template data file.
* @return void
*/
static public function register_templates( $path = false )
{
if ( $path && file_exists( $path ) ) {
self::$templates[] = $path;
}
}
/**
* Apply a core template.
*
* @since 1.0
* @since 1.5.7. Added logic for overriding core templates.
* @param int $index The index of the template to apply.
* @param bool $append Whether to append the new template or replacing the existing layout.
* @return void
*/
static public function apply_template($index = 0, $append = false)
{
// Allow extensions to hook into applying a template.
$override = apply_filters( 'fl_builder_override_apply_template', false, array(
'index' => $index,
'append' => $append
) );
// Return if we have an override from the filter.
if ( $override ) {
return;
}
// Apply a core template.
$template = self::get_template($index);
$row_position = self::next_node_position('row');
// Delete existing nodes and settings?
if(!$append) {
self::delete_layout_data('draft');
self::delete_layout_settings('draft');
}
// Only move forward if we have template nodes.
if(isset($template->nodes)) {
// Get new ids for the template nodes.
$template->nodes = self::generate_new_node_ids($template->nodes);
// Get the existing layout data and settings.
$layout_data = self::get_layout_data();
$layout_settings = self::get_layout_settings();
// Reposition rows?
if($append) {
foreach($template->nodes as $node_id => $node) {
if($node->type == 'row') {
$template->nodes[$node_id]->position += $row_position;
}
}
}
// Merge and update the layout data.
$data = array_merge($layout_data, $template->nodes);
self::update_layout_data($data);
// Merge and update the layout settings.
if ( isset( $template->settings ) ) {
$settings = self::merge_layout_settings( $layout_settings, $template->settings );
self::update_layout_settings( $settings );
}
}
// Delete old asset cache.
self::delete_asset_cache();
}
/**
* Returns data for a core template.
*
* @since 1.0
* @param int $index The index of the template.
* @param string $type The type of template to get. Currently either layout, row or module.
* @return object
*/
static public function get_template( $index, $type = 'layout' )
{
$templates = self::get_templates( $type );
return isset( $templates[ $index ] ) ? $templates[ $index ] : false;
}
/**
* Returns data for all core or third party templates.
*
* @since 1.0
* @param string $type Either layout, row or module
* @return array
*/
static public function get_templates( $type = 'layout' )
{
$templates = array();
foreach ( self::$templates as $path ) {
if ( file_exists( $path ) ) {
if ( stristr( $path, '.php' ) ) {
ob_start();
include $path;
$unserialized = unserialize( ob_get_clean() );
}
else {
$unserialized = unserialize( file_get_contents( $path ) );
}
if ( is_array( $unserialized ) ) {
if ( isset( $unserialized[ $type ] ) ) {
$templates = array_merge( $templates, $unserialized[ $type ] );
}
else if ( 'layout' == $type ) {
$templates = array_merge( $templates, $unserialized );
}
}
}
}
return apply_filters( 'fl_builder_get_templates', $templates, $type );
}
/**
* Checks to see if any templates exist.
*
* @since 1.8
* @return bool
*/
static public function has_templates()
{
return apply_filters( 'fl_builder_has_templates', ( count( self::get_templates() ) > 0 ) );
}
/**
* Returns template data needed for the template selector.
* Can also return data for row and module templates if
* a template type is passed.
*
* @since 1.5.7
* @param string $type Either layout, row or module
* @return array
*/
static public function get_template_selector_data( $type = 'layout' )
{
$categorized = array();
$templates = array();
$core_categories = array(
'landing' => __( 'Landing Pages', 'fl-builder' ),
'company' => __( 'Content Pages', 'fl-builder' )
);
// Build the the templates array.
foreach( self::get_templates( $type ) as $key => $template ) {
if ( 'module' == $type ) {
$node = array_shift( $template->nodes );
if ( ! isset( self::$modules[ $node->settings->type ] ) ) {
continue;
}
}
if ( strstr( $template->image, '://' ) ) {
$image = $template->image;
}
else {
$image = FL_BUILDER_URL . 'img/templates/' . ( empty( $template->image ) ? 'blank.jpg' : $template->image );
}
$template_data = array(
'id' => $key,
'name' => $template->name,
'image' => $image,
'category' => isset( $template->category ) ? $template->category : $template->categories,
'type' => 'core'
);
$template_data = apply_filters( 'fl_builder_template_selector_data', $template_data, $template );
$templates[] = $template_data;
}
// Build the categorized templates array.
foreach( $templates as $template ) {
if ( ! isset( $template['category'] ) ) {
continue;
}
if ( is_array( $template['category'] ) ) {
foreach ( $template['category'] as $cat_key => $cat_label ) {
if ( ! isset( $categorized[ $cat_key ] ) ) {
$categorized[ $cat_key ] = array(
'name' => $cat_label,
'templates' => array()
);
}
$categorized[ $cat_key ]['templates'][] = $template;
}
}
else {
if ( ! isset( $categorized[ $template['category'] ] ) ) {
$categorized[ $template['category'] ] = array(
'name' => $core_categories[ $template['category'] ],
'templates' => array()
);
}
$categorized[ $template['category'] ]['templates'][] = $template;
}
}
// Return both the templates and categorized templates array.
return apply_filters( 'fl_builder_template_selector_data', array(
'templates' => $templates,
'categorized' => $categorized
), $type );
}
/**
* Returns data needed for the template selector's category filter.
*
* @since 1.8
* @return array
*/
static public function get_template_selector_filter_data()
{
$templates = self::get_template_selector_data();
$data = array();
foreach ( $templates['categorized'] as $slug => $category ) {
$data[ $slug ] = $category['name'];
}
return apply_filters( 'fl_builder_template_selector_filter_data', $data );
}
/**
* Returns data for row templates to be shown in the UI panel.
*
* @since 1.8
* @return array
*/
static public function get_row_templates_data()
{
return apply_filters( 'fl_builder_row_templates_data', self::get_template_selector_data( 'row' ) );
}
/**
* Returns data for module templates to be shown in the UI panel.
*
* @since 1.8
* @return array
*/
static public function get_module_templates_data()
{
return apply_filters( 'fl_builder_module_templates_data', self::get_template_selector_data( 'module' ) );
}
/**
* Get color presets.
*
* @since 1.6.4
* @return object
*/
static public function get_color_presets()
{
$settings = get_option( '_fl_builder_color_presets', array() );
return apply_filters( 'fl_builder_color_presets', $settings );
}
/**
* Save color presets.
*
* @since 1.6.4
* @param array $presets The new color presets collection.
* @return object
*/
static public function save_color_presets( $presets = array() )
{
return update_option( '_fl_builder_color_presets', $presets );
}
/**
* Returns the custom branding string.
*
* @since 1.3.1
* @return string
*/
static public function get_branding()
{
if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
return FLBuilderWhiteLabel::get_branding();
}
return __( 'Page Builder', 'fl-builder' );
}
/**
* Returns the custom branding icon URL.
*
* @since 1.3.7
* @return string
*/
static public function get_branding_icon()
{
if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
return FLBuilderWhiteLabel::get_branding_icon();
}
return FL_BUILDER_URL . 'img/beaver.png';
}
/**
* Returns an array of slugs for all enabled icon sets.
*
* @since 1.4.6
* @return array
*/
static public function get_enabled_icons()
{
$value = self::get_admin_settings_option( '_fl_builder_enabled_icons', true );
return ! $value ? array( 'font-awesome', 'foundation-icons', 'dashicons' ) : $value;
}
/**
* Returns the capability necessary for a user to access all
* editing features in the builder interface.
*
* @since 1.3.9
* @return string
*/
static public function get_editing_capability()
{
$value = self::get_admin_settings_option( '_fl_builder_editing_capability', true );
return ! $value ? 'edit_posts' : $value;
}
/**
* Checks to see if the current user has the capability necessary
* to use the builders advanced editing features.
*
* @since 1.7
* @return bool
*/
static public function current_user_has_editing_capability()
{
$cap = self::get_editing_capability();
return self::current_user_has_capability($cap);
}
/**
* Check if the current user has the specific capabilities
*
* @param string $cap The capability to evaluate if it's single or multiple (comma separated) value
* @return bool
*/
static public function current_user_has_capability($cap)
{
if ( strstr( $cap, ',' ) ) {
$parts = explode( ',', $cap );
foreach( $parts as $part ) {
if ( current_user_can( trim( $part ) ) ) {
return true;
}
}
return false;
}
else {
return current_user_can( $cap );
}
}
/**
* Returns the capability necessary for a user to edit global templates.
*
* @since 1.6.3
* @return string
*/
static public function get_global_templates_editing_capability()
{
$value = self::get_admin_settings_option( '_fl_builder_global_templates_editing_capability', true );
return ! $value ? 'edit_posts' : $value;
}
/**
* Returns the default settings for the builder's help button.
*
* @since 1.4.9
* @return array
*/
static public function get_help_button_defaults()
{
$defaults = array(
'enabled' => true,
'tour' => true,
'video' => true,
'video_embed' => '',
'knowledge_base' => true,
'knowledge_base_url' => self::get_store_url( 'knowledge-base', array( 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ), 'utm_source' => 'builder-ui', 'utm_campaign' => 'kb-help-button' ) ),
'forums' => true,
'forums_url' => self::get_store_url( 'knowledge-base', array( 'utm_medium' => ( true === FL_BUILDER_LITE ? 'bb-lite' : 'bb-pro' ), 'utm_source' => 'builder-ui', 'utm_campaign' => 'forums-help-button' ) )
);
return $defaults;
}
/**
* Returns the settings for the builder's help button.
*
* @since 1.4.9
* @return array
*/
static public function get_help_button_settings()
{
if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
return FLBuilderWhiteLabel::get_help_button_settings();
}
return self::get_help_button_defaults();
}
/**
* Returns an array of account data for all integrated services.
*
* @since 1.5.4
* @return array
*/
static public function get_services()
{
return get_option( '_fl_builder_services', array() );
}
/**
* Updates the account data for an integrated service.
*
* @since 1.5.4
* @param string $service The service id.
* @param string $account The account name.
* @param array $data The account data.
* @return void
*/
static public function update_services( $service, $account, $data )
{
$services = self::get_services();
$account = sanitize_text_field( $account );
if ( ! isset( $services[ $service ] ) ) {
$services[ $service ] = array();
}
$services[ $service ][ $account ] = $data;
update_option( '_fl_builder_services', $services );
}
/**
* Deletes an account for an integrated service.
*
* @since 1.5.4
* @param string $service The service id.
* @param string $account The account name.
* @return void
*/
static public function delete_service_account( $service, $account )
{
$services = self::get_services();
if ( isset( $services[ $service ][ $account ] ) ) {
unset( $services[ $service ][ $account ] );
}
if ( 0 === count( $services[ $service ] ) ) {
unset( $services[ $service ] );
}
update_option( '_fl_builder_services', $services );
}
/**
* Returns an option from the database for
* the admin settings page.
*
* @since 1.5.7
* @param string $key The option key.
* @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
* @return mixed
*/
static public function get_admin_settings_option( $key, $network_override = true )
{
// Get the site-wide option if we're in the network admin.
if ( is_network_admin() ) {
$value = get_site_option( $key );
}
// Get the site-wide option if network overrides aren't allowed.
else if ( ! $network_override && class_exists( 'FLBuilderMultisiteSettings' ) ) {
$value = get_site_option( $key );
}
// Network overrides are allowed. Return the subsite option if it exists.
else if ( class_exists( 'FLBuilderMultisiteSettings' ) ) {
$value = get_option( $key );
$value = false === $value ? get_site_option( $key ) : $value;
}
// This must be a single site install. Get the single site option.
else {
$value = get_option( $key );
}
return $value;
}
/**
* Updates an option from the admin settings page.
*
* @since 1.5.7
* @param string $key The option key.
* @param mixed $value The value to update.
* @param bool $network_override Whether to allow the network admin setting to be overridden on subsites.
* @return mixed
*/
static public function update_admin_settings_option( $key, $value, $network_override = true )
{
// Update the site-wide option since we're in the network admin.
if ( is_network_admin() ) {
update_site_option( $key, $value );
}
// Delete the option if network overrides are allowed and the override checkbox isn't checked.
else if ( $network_override && FLBuilderAdminSettings::multisite_support() && ! isset( $_POST['fl-override-ms'] ) ) {
delete_option( $key );
}
// Update the option for single install or subsite.
else {
update_option( $key, $value );
}
}
/**
* Returns the plugin basename for Beaver Builder.
*
* @since 1.0
* @return string
*/
static public function plugin_basename()
{
return plugin_basename( FL_BUILDER_DIR . 'fl-builder.php' );
}
/**
* Deletes almost all database data and asset cache for the builder.
* We don't delete _fl_builder_enabled, _fl_builder_data and _fl_builder_draft
* so layouts can be recovered should the plugin be installed again.
*
* @since 1.0
* @return void
*/
static public function uninstall_database()
{
if(current_user_can('delete_plugins')) {
// Delete builder options.
delete_option('_fl_builder_settings');
delete_option('_fl_builder_enabled_modules');
delete_option('_fl_builder_enabled_templates');
delete_option('_fl_builder_user_templates_admin');
delete_option('_fl_builder_template_data_exporter');
delete_option('_fl_builder_templates_override');
delete_option('_fl_builder_templates_override_rows');
delete_option('_fl_builder_templates_override_modules');
delete_option('_fl_builder_post_types');
delete_option('_fl_builder_enabled_icons');
delete_option('_fl_builder_branding');
delete_option('_fl_builder_branding_icon');
delete_option('_fl_builder_theme_branding');
delete_option('_fl_builder_editing_capability');
delete_option('_fl_builder_global_templates_editing_capability');
delete_option('_fl_builder_help_button');
delete_option('_fl_builder_color_presets');
// Delete builder user meta.
delete_metadata('user', 0, '_fl_builder_launched', 1, true);
// Delete uploaded files and folders.
$upload_dir = self::get_upload_dir();
$filesystem = FLBuilderUtils::get_filesystem();
$filesystem->rmdir( $upload_dir['path'], true );
// Deactivate and delete the plugin.
if (!function_exists('deactivate_plugins')) {
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
deactivate_plugins(array(self::plugin_basename()), false, is_network_admin());
delete_plugins(array(self::plugin_basename()));
// Redirect to the plugins page.
wp_redirect(admin_url('plugins.php?deleted=true&plugin_status=all&paged=1&s='));
exit;
}
}
/**
* @since 1.6.4.3
* @deprecated 1.8
*/
static public function get_theme_branding()
{
_deprecated_function( __METHOD__, '1.8', 'FLBuilderWhiteLabel::get_theme_branding()' );
if ( class_exists( 'FLBuilderWhiteLabel' ) ) {
return FLBuilderWhiteLabel::get_theme_branding();
}
}
/**
* @since 1.0
* @deprecated 1.8
*/
static public function save_templates( $templates = array() )
{
_deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_templates()' );
if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
FLBuilderCoreTemplatesAdmin::save_templates( $templates );
}
}
/**
* @since 1.0
* @deprecated 1.8
*/
static public function save_template( $settings )
{
_deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::save_template()' );
if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
FLBuilderCoreTemplatesAdmin::save_template( $settings );
}
}
/**
* @since 1.0
* @deprecated 1.8
*/
static public function update_template( $old_index, $settings )
{
_deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::update_template()' );
if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
FLBuilderCoreTemplatesAdmin::update_template( $old_index, $settings );
}
}
/**
* @since 1.0
* @deprecated 1.8
*/
static public function delete_template( $index )
{
_deprecated_function( __METHOD__, '1.8', 'FLBuilderCoreTemplatesAdmin::delete_template()' );
if ( class_exists( 'FLBuilderCoreTemplatesAdmin' ) ) {
FLBuilderCoreTemplatesAdmin::delete_template( $index );
}
}
}
FLBuilderModel::init();
Subscribe Form Signup Subscribe Now Subscribe! Success Success Action Success URL Tabs Take a Tour Target URL Template Saved! Template Settings Template edit form field label. Is template premium one?Premium Template edit form field label. Template name.Name Template name.Blank Template name.Name Templates Templates category label.Company Info Templates category label.Landing Pages Templates list column label.Category Templates list column label.Name Templates list column label. Is template premium one?Premium Testimonial Testimonials Text Text & Photo Text & Video Text Background Color Text Background Gradient Text Background Height Text Background Opacity Text Color Text Colors Text Editor Text Hover Color Text Padding Text Position Text Shadow Text Width Thanks for subscribing! Please check your email for further instructions. The Page Builder plugin requires WordPress version 3.5 or greater. Please update WordPress before activating the plugin. The Target URL field correlates to the page you would like your social icons to interface with. For example, if you show Facebook, the user will "Like" whatever you put in this field. The alignment that will apply to all elements within the callout. The amount of time in seconds before this animation starts. The browser width at which the layout will adjust for medium devices such as tablets. The browser width at which the layout will adjust for small devices such as phones. The builder does not delete the post meta _fl_builder_data
, _fl_builder_draft
and _fl_builder_enabled
in case you want to reinstall it later. If you do, the builder will rebuild all of its data using those meta values. The caption pulls from whatever text you put in the caption area in the media manager for each image. The caption is also pulled directly from SmugMug if you have captions set in your gallery. The color applies to the overlay behind text over the background selections. The email address associated with your Mad Mimi account. The filename of the image such as "thumb.jpg" that resides in the "img/templates/" directory. The first %s stands for custom branded "Page Builder" name. The second %s stands for the post type name.%s is currently active for this %s. The link applies to the entire module. If choosing a call to action type below, this link will also be used for the text or button. The link applies to the entire slide. If choosing a call to action type below, this link will also be used for the text or button. The max width that the content area will be within your slides. The position will move the content layout selections left or right or center of the thumbnail of the slide. The position will move the content layout selections left, right or bottom over the background of the slide. The position will move the content layout selections left, right or center over the background of the slide. The settings you are currently editing will not be saved if you navigate away from this page. The type of border to use. Double borders must have a height of at least 3px to render properly. The type of border to use. Double borders must have a width of at least 3px to render properly. The width of this column on medium devices such as tablets. The width of this column on small devices such as phones. There was a problem retrieving your lists. Please check your API credentials. There was an error connecting to AWeber. Please try again. There was an error connecting to Infusionsoft. %s There was an error connecting to SendinBlue. Please try again. There was an error retrieveing your lists. There was an error subscribing to AWeber. %s There was an error subscribing to AWeber. The account is no longer connected. There was an error subscribing to ActiveCampaign. The account is no longer connected. There was an error subscribing to Campaign Monitor. There was an error subscribing to Campaign Monitor. The account is no longer connected. There was an error subscribing to Constant Contact. %s There was an error subscribing to Constant Contact. The account is no longer connected. There was an error subscribing to GetResponse. %s There was an error subscribing to GetResponse. The account is no longer connected. There was an error subscribing to Hatchbuck. There was an error subscribing to Hatchbuck. The API key is invalid. There was an error subscribing to Hatchbuck. The account is no longer connected. There was an error subscribing to Infusionsoft. %s There was an error subscribing to Infusionsoft. The account is no longer connected. There was an error subscribing to Mad Mimi. The account is no longer connected. There was an error subscribing to MailChimp. %s There was an error subscribing to MailChimp. The account is no longer connected. There was an error subscribing to SendinBlue. Please try again. There was an error subscribing to SendinBlue. The account is no longer connected. There was an error subscribing to iContact. %s There was an error subscribing to iContact. The account is no longer connected. There was an error subscribing. MailPoet is not installed. There was an error subscribing. Please try again. There was an error subscribing. The account is no longer connected. Third party service such as MailChimp.Error: Missing service type. This allows you to add content over or in addition to the background selection above. The location of the content layout can be selected in the style tab. This applies to all sites on the network. This only applies to this site. Please visit the Network Admin Settings to clear the cache for all sites on the network. This setting is for the entire background of your slide. This setting is the minimum height of the content slider. Content will expand the height automatically. This setting is the minimum height of the post slider. Content will expand the height automatically. This version of the Page Builder plugin is not compatible with WordPress Multisite. Please upgrade to the Multisite version of this plugin. Thumbnail Thumbs Thumbs Button Thumbs Size Title Title Size Tools Top Top Margin Top Rated Products Top Width Transition Transition Speed Transition type.Slide Transparent Twitter Button Type UPDATES UNAVAILABLE! Please subscribe or enter your license key below to enable automatic updates. URL Unable to connect to Mad Mimi. Please check your credentials. Uninstall Update Template Updates & Support Subscription Upgrade Upload Icon Set Upload a photo or display one from the media library. Uppercase Use Icon for Posts Use Main Photo Use the Add Content button to open the content panel and add new row layouts, modules or widgets. Use the Templates button to pick a new template or append one to your layout. Appending will insert a new template at the end of your existing page content. Use the action buttons to perform actions such as moving, editing, duplicating or deleting rows, columns and modules. Use this setting to edit builder templates in the WordPress admin. Use this setting to enable or disable templates in the builder interface. Use this setting to override core builder templates with your templates. Use this to normalize the height of your boxes when they have different numbers of features. Used to identify this connection within the accounts list and can be anything you like. Username Value unit for form field of time in seconds. Such as: "5 seconds"seconds Vertical Vertical Spacing Video Video Embed Code Video Type Video preview/fallback image.Poster View the Knowledge Base WARNING! You are about to delete a global template that may be linked to other pages. Do you really want to delete this template and unlink it? Warning! Changing the template will replace your existing layout. Do you really want to do this? Watch the Video Welcome! It looks like this might be your first time using the builder. Would you like to take a tour? What would you like to do? When auto spacing is enabled, the builder will automatically adjust the margins and padding in your layout once the small device breakpoint is reached. Most users will want to leave this enabled. Wide Wide is for 1 column rows, compact is for multi-column rows. Widget Width Width.Auto WooCommerce WordPress Widgets Yes Yes Please! You can choose a different photo that the slide will change to on mobile devices or no photo if desired. You haven't saved any templates yet! To do so, create a layout and save it as a template under Tools → Save Template. You must create an app in iContact to obtain an app ID and password. Please see the iContact docs for complete instructions. You must register a Developer Account with Constant Contact to obtain an API key and access token. Please see Getting an API key for complete instructions. Your API key can be found in your Campaign Monitor account under Account Settings > API Key. Your API key can be found in your GetResponse account under My Account > GetResponse API. Your API key can be found in your Hatchbuck account under Account Settings > Web API. Your API key can be found in your Infusionsoft account under Admin > Settings > Application > API > Encrypted Key. Your API key can be found in your Mad Mimi account under Account > Settings & Billing > API. Your API key can be found in your MailChimp account under Account > Extras > API Keys. Your Access Key can be found in your SendinBlue account under API & Integration > Manager Your Keys > Version 2.0 > Access Key. Your App ID can be found in the URL for your account. For example, if the URL for your account is myaccount.infusionsoft.com, your App ID would be myaccount. Your Constant Contact API key. Your Constant Contact access token. Your Message Your Templates Your email Your iContact app ID. Your iContact app password. Your iContact username. Your message Your name Your phone example@mail.com http://www.example.com http://www.example.com/my-photo.jpg per Year PO-Revision-Date: 2016-04-06 02:07:36+0000
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;
X-Generator: GlotPress/2.2.2
Language: cs_CZ
Project-Id-Version: BB-Plugin
Tlačítko “Vložit do košíku” "{message}" na řádku {line} souboru {file}. Autor: %s Nastavení pro %s Spustit %s %s → upravit Kopie %s Soubor %s.php modulu už existuje! Použijte, prosím, předponu v názvech Vašich souborů modulu tak, aby byla zachovaná kompatibilita s Beaver Builder modulem. %s už neexistuje 1 sloupec 1 obrázek zvolený %d obrázky zvolené %d obrázků zvolených Plzeň, Česká republika 2 sloupce 3 sloupce 4 sloupce 5 sloupců 6 sloupců AKTUALIZACE NEDOSTUPNÉ