$post_type_enabled) { if(post_type_exists($post_type_name) && $post_type_enabled == '1') { $enabled_screen_ids[] = $post_type_name; $enabled_screen_ids[] = 'edit-' . $post_type_name; } } $is_enabled = in_array($current_screen->id, $enabled_screen_ids); $is_enabled = apply_filters('F4/TREE/Tree/is_tree_enabled', $is_enabled, $current_screen); return $is_enabled; } /** * Check if tree is enabled for this post type * * @since 1.0.0 * @access public * @static * @return bool True if the tree is enabled for this post type */ public static function is_tree_post_type($post_type) { if(is_object($post_type)) { $post_type = $post_type->post_type; } elseif(is_numeric($post_type)) { $post_id = $post_type; $post_type = get_post_type($post_id); if($post_type === 'revision') { $post_type = get_post_type(wp_get_post_parent_id($post_id)); } } $enabled_post_types = Core::get_settings('post-types'); $enabled_post_types['nav_menu_item'] = '1'; $is_tree_post_type = isset($enabled_post_types[$post_type]); $is_tree_post_type = apply_filters('F4/TREE/Tree/is_tree_post_type', $is_tree_post_type, $post_type); return $is_tree_post_type; } /** * Update changed timestamp * * @since 1.0.0 * @access public * @static * @return int The updated timestamp */ public static function update_changed_timestamp($time = null) { if(!$time) { $time = time(); } $time = apply_filters('F4/TREE/Tree/update_changed_timestamp', $time); update_option('f4-tree-changed-timestamp', $time); return $time; } /** * Get changed timestamp * * @since 1.0.0 * @access public * @static * @return int The last changed timestamp */ public static function get_changed_timestamp() { $changed_timestamp = get_option('f4-tree-changed-timestamp', 0); $changed_timestamp = apply_filters('F4/TREE/Tree/get_changed_timestamp', $changed_timestamp); return $changed_timestamp; } /** * Clear changed timestamp cache * * @since 1.0.0 * @access public * @static */ public static function clear_changed_timestamp_cache() { wp_cache_delete('alloptions', 'options'); do_action('F4/TREE/Tree/clear_changed_timestamp_cache'); } /** * Get the icon for a node * * @since 1.0.0 * @access public * @static */ public static function get_node_icon($type, $object, $id, $status) { // Icon: Default (external link) $icon = array( 'html' => ' ' ); // Icon: Post types if($type === 'post_type') { if($object === 'page') { // WooCommerce pages // @todo: move to plugins hooks if(function_exists('is_woocommerce')) { if(wc_get_page_id('cart') == $id) { // Cart $icon = array( 'html' => ' ' ); } elseif(wc_get_page_id('checkout') == $id) { // Checkout $icon = array( 'html' => ' ' ); } elseif(wc_get_page_id('shop') == $id) { // Shop $icon = array( 'html' => ' ' ); } elseif(wc_get_page_id('myaccount') == $id) { // My Account $icon = array( 'html' => ' ' ); } else { $icon = array( 'html' => ' ' ); } } else { $icon = array( 'html' => ' ' ); } } else { $menu_icon = get_post_type_object($object)->menu_icon; $menu_icon = !$menu_icon ? 'dashicons-admin-post' : $menu_icon; $icon = array( 'html' => '' ); } // Icon: Home if($object === 'page') { $page_on_front = (int)Core::maybe_translate_post_id(get_option('page_on_front')); if($page_on_front && $id === $page_on_front) { $icon = array( 'html' => ' ' ); } } } elseif($type === 'taxonomy') { $icon = array( 'html' => ' ' ); } // Modify node icon $icon = apply_filters('F4/TREE/Menu/get_node_icon', $icon, $type, $object, $id, $status); return $icon; } /** * Get tree node for a post * * @since 1.0.0 * @access public * @static */ public static function get_post_tree_node($post_item, $current_post_id) { // Create default node $node_item = array( 'key' => 'post-' . uniqid(), 'title' => (empty($post_item->post_title) ? __( '(no title)') : $post_item->post_title), 'tooltip' => 'ID: ' . $post_item->ID, 'icon' => self::get_node_icon('post_type', $post_item->post_type, $post_item->ID, $post_item->post_status), 'active' => ($post_item->ID == $current_post_id), 'expanded' => ($post_item->ID == $current_post_id), 'extraClasses' => array(), 'data' => array( 'url' => get_admin_url(null, 'post.php?post=' . $post_item->ID . '&action=edit'), 'type' => 'post', 'post_id' => $post_item->ID, 'post_type' => $post_item->post_type, 'post_status' => $post_item->post_status, 'allow_children' => false ) ); // Disable drag and drop if no permission if(!Core::current_user_can_post_cap('edit_post', $post_item->ID, $post_item->post_type)) { $node_item['extraClasses'][] = 'node-disable-dnd'; } // Add children if hierarchical if(is_post_type_hierarchical($post_item->post_type)) { $node_item['data']['allow_children'] = true; $node_item['children'] = self::get_children($post_item->post_type, $post_item->ID, $current_post_id); } $node_item = apply_filters('F4/TREE/Tree/get_post_tree_node', $node_item, $post_item, $current_post_id); return $node_item; } /** * Get tree children * * @since 1.0.0 * @access public * @static */ public static function get_children($post_type = 'page', $post_parent = 0, $post_id = null, $recursive = true, $args = array()) { if(!$post_id) { $post_id = get_the_ID(); } // Set defaults $args = wp_parse_args( $args, array( 'suppress_filters' => false, 'nopaging' => true, 'orderby' => array( 'menu_order' => 'ASC', 'title' => 'ASC' ), 'post_status' => array( 'draft', 'publish', 'future', 'pending', 'private' ) ) ); // Force arguments $args['post_parent'] = $post_parent; $args['post_type'] = $post_type; // Get posts $posts = get_posts($args); // Get tree nodes $tree_nodes = array(); foreach($posts as $post_item) { // Skip private posts if no permission //if($post_item->post_status === 'private' && !Core::current_user_can_post_cap('read_private_posts', $post_item->ID, $post_item->post_type)) { if($post_item->post_status === 'private' && !current_user_can('read_private_posts', $post_item->ID)) { continue; } $tree_nodes[] = self::get_post_tree_node($post_item, $post_id); } return $tree_nodes; } /** * Get the tree * * @since 1.0.0 * @access public * @static */ public static function get_tree($post_id, $post_type = 'page') { // Get post type object $post_type_object = get_post_type_object($post_type); // Get child nodes $post_nodes = self::get_children($post_type, 0, $post_id); $post_nodes = apply_filters('F4/TREE/Tree/get_tree_post_nodes', $post_nodes, $post_id, $post_type, $post_type_object); // Build tree $tree_nodes = apply_filters('F4/TREE/Tree/get_tree_nodes_before', array(), $post_id, $post_type, $post_type_object, $post_nodes); $tree_nodes[] = array( 'key' => 'pool-' . $post_type, 'title' => $post_type_object->label, 'expanded' => true, 'folder' => 1, 'unselectable' => 1, 'extraClasses' => 'node-disable-dnd tree-pool', 'children' => array_values($post_nodes), 'icon' => array( 'html' => ' ' ), 'tooltip' => $post_type_object->description, 'data' => array( 'type' => 'pool', 'allow_children' => true ) ); $tree_nodes = apply_filters('F4/TREE/Tree/get_tree_nodes_after', $tree_nodes, $post_id, $post_type, $post_type_object, $post_nodes); $tree_nodes = array_values($tree_nodes); // Check for duplicate active nodes $has_active_node = false; array_walk_recursive($tree_nodes, function(&$v, $k) { global $has_active_node; if($k === 'active') { if($has_active_node) { $v = false; } if($v) { $has_active_node = true; } } }); return $tree_nodes; } } ?>