is 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 alเช เชฏเชเชคเซเชฐ