Custom WordPress plugin that replaces the default flat media library with a structured folder view. Features: hierarchical folders via custom taxonomy, sidebar folder tree, drag & drop, modal integration with Elementor/builders, bulk assign, upload auto-assign, toast notifications. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
123 lines
2.7 KiB
PHP
123 lines
2.7 KiB
PHP
<?php
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class MFP_Taxonomy {
|
|
|
|
public const TAXONOMY = 'media_folder';
|
|
|
|
public function register(): void {
|
|
register_taxonomy( self::TAXONOMY, 'attachment', [
|
|
'labels' => [
|
|
'name' => __( 'Foldery mediów', 'media-folder-pro' ),
|
|
'singular_name' => __( 'Folder mediów', 'media-folder-pro' ),
|
|
'add_new_item' => __( 'Dodaj nowy folder', 'media-folder-pro' ),
|
|
'edit_item' => __( 'Edytuj folder', 'media-folder-pro' ),
|
|
],
|
|
'hierarchical' => true,
|
|
'public' => false,
|
|
'show_ui' => false,
|
|
'show_in_rest' => true,
|
|
'show_admin_column' => false,
|
|
'query_var' => false,
|
|
'rewrite' => false,
|
|
] );
|
|
}
|
|
|
|
/**
|
|
* @return array<int, array{id: int, name: string, slug: string, parent: int, count: int, children: array}>
|
|
*/
|
|
public function get_folder_tree(): array {
|
|
$terms = get_terms( [
|
|
'taxonomy' => self::TAXONOMY,
|
|
'hide_empty' => false,
|
|
'orderby' => 'name',
|
|
'order' => 'ASC',
|
|
] );
|
|
|
|
if ( is_wp_error( $terms ) || empty( $terms ) ) {
|
|
return [];
|
|
}
|
|
|
|
$flat = [];
|
|
foreach ( $terms as $term ) {
|
|
$flat[ $term->term_id ] = [
|
|
'id' => $term->term_id,
|
|
'name' => $term->name,
|
|
'slug' => $term->slug,
|
|
'parent' => $term->parent,
|
|
'count' => (int) $term->count,
|
|
'children' => [],
|
|
];
|
|
}
|
|
|
|
$tree = [];
|
|
foreach ( $flat as $id => &$node ) {
|
|
if ( $node['parent'] === 0 ) {
|
|
$tree[] = &$flat[ $id ];
|
|
} elseif ( isset( $flat[ $node['parent'] ] ) ) {
|
|
$flat[ $node['parent'] ]['children'][] = &$flat[ $id ];
|
|
} else {
|
|
$tree[] = &$flat[ $id ];
|
|
}
|
|
}
|
|
unset( $node );
|
|
|
|
return $tree;
|
|
}
|
|
|
|
public function folder_has_children( int $folder_id ): bool {
|
|
$children = get_terms( [
|
|
'taxonomy' => self::TAXONOMY,
|
|
'parent' => $folder_id,
|
|
'hide_empty' => false,
|
|
'number' => 1,
|
|
'fields' => 'ids',
|
|
] );
|
|
|
|
if ( ! empty( $children ) ) {
|
|
return true;
|
|
}
|
|
|
|
$attachments = get_posts( [
|
|
'post_type' => 'attachment',
|
|
'post_status' => 'inherit',
|
|
'tax_query' => [
|
|
[
|
|
'taxonomy' => self::TAXONOMY,
|
|
'terms' => $folder_id,
|
|
],
|
|
],
|
|
'posts_per_page' => 1,
|
|
'fields' => 'ids',
|
|
] );
|
|
|
|
return ! empty( $attachments );
|
|
}
|
|
|
|
public function would_create_cycle( int $folder_id, int $new_parent_id ): bool {
|
|
if ( $new_parent_id === 0 ) {
|
|
return false;
|
|
}
|
|
if ( $folder_id === $new_parent_id ) {
|
|
return true;
|
|
}
|
|
|
|
$current = $new_parent_id;
|
|
while ( $current !== 0 ) {
|
|
$term = get_term( $current, self::TAXONOMY );
|
|
if ( is_wp_error( $term ) || ! $term ) {
|
|
break;
|
|
}
|
|
if ( $term->parent === $folder_id ) {
|
|
return true;
|
|
}
|
|
$current = $term->parent;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|